---
title: Retrieve policy periods and select the current/renewal period
summary: Loads all policy terms for a policy and provides helpers to select the current, renewal, or date-effective period.
status: draft
owner: SAIF Corporation
last_reviewed: 2026-09-01
library: SAIF.Business.View.Policy
reference_type: embedded
operation_id: op-03-retrieve-policy-periods
trigger: Consumer reads PolicyPeriods
---

# Retrieve policy periods and select the current/renewal period

Loads all policy periods (terms) for a policy into a `clsPolicyPeriodCollection`, and provides selection helpers for the current period, the latest period with a printed information page, and the period effective on an arbitrary date.

| Field | Value |
| --- | --- |
| **Operation ID** | op-03-retrieve-policy-periods |
| **Trigger** | Consumer reads `PolicyPeriods` (backed by `clsPolicyPeriodCollection.GetPolicyPeriodCollection`) |
| **Inputs** | Policy number, optional top-N period limit |
| **Outputs** | `clsPolicyPeriodCollection`; `GetCurrentPolicyPeriod`/`GetLatestPolicyPeriodInfoPagePrinted`/`GetDOIPolicyPeriod` return a single `clsPolicyPeriod` |
| **Primary components** | `clsPolicyPeriodCollection.GetPolicyPeriodCollection`, `clsPolicyData.GetCurrentPolicyPeriod`, `GetLatestPolicyPeriodInfoPagePrinted`, `GetDOIPolicyPeriod` |
| **Entry point** | `SAIF.Business.View.Policy/clsPolicyPeriodCollection.vb`, `SAIF.Business.View.Policy/clsPolicyData.vb` |

## Steps

1. Caller invokes `clsPolicyPeriodCollection.GetPolicyPeriodCollection(inDataportal, inPolicyNum[, inTopNPolicyPeriods])`, which constructs a `Criteria` and delegates to `inDataportal.DataAccessLayer.RetrieveObject`.
2. Framework invokes `BeforeRetrieve`: creates a new `IDataRequest`, assigns `MyCriteria.RetrieveSQL` (constant `"pk72846_view_policy.getPolicyPeriods"`, [SQL-022](../sql/SQL-022-getpolicyperiods.md)), sets `CommandType = StoredProcedure`, and binds `apolicynum` and `aTopNPolPer` (from `MyCriteria.TopNPolicyPeriods`, defaulting to `0` when the two-argument overload is used) plus a cursor parameter `recordset`.
3. Framework executes the procedure against Oracle.
4. Framework invokes `AfterRetrieve`: casts the result to `IDataReader`, loops `Reader.Read`, and for each row constructs a `New clsPolicyPeriod`, calls `PolicyPeriod.Load(CriteriaObject.DataPortalInfo, Reader)`, and adds it via `MyBase.Add`.
5. Once populated, `clsPolicyData.GetCurrentPolicyPeriod()` iterates `PolicyPeriods` and returns the first period where `isCurrentPolicyPeriod` is true; if none match, it falls back to `PolicyPeriods(0)` (the first period in retrieval order), or `Nothing` if the collection is empty ([BR-VP-018](../business-rules.md#br-vp-018-currentrenewal-period-selection)).
6. `GetLatestPolicyPeriodInfoPagePrinted()` iterates `PolicyPeriods` and returns the first period that is both `isRenewalPolicyPeriod` and has its information page printed (via `IsInformationPagePrinted`, see [Lazy retrieval of policy detail and indicators](op-02-lazy-retrieve-policy-detail.md)); if a period is `isCurrentPolicyPeriod` it is returned instead without the printed check; otherwise falls back to `PolicyPeriods(0)` or `Nothing` ([BR-VP-019](../business-rules.md#br-vp-019-latest-printed-information-page-period)).
7. `GetDOIPolicyPeriod(inDOI)`, `GetDOISalesPlan(inDOI)`, and `GetDOIFinalEvalDate(inDOI)` all delegate to `PolicyPeriods.ItemEffectiveAtDOI(inDOI)`, a collection indexer that returns the first period where `inDOI` falls within `[PolicyPeriodEffDate, PolicyPeriodExpDate)`; the sales-plan and final-eval-date helpers return sentinel values (`"Not Found"`, `Date.MinValue`) when no period matches rather than raising an exception.

## Process flow

```mermaid
flowchart TD
	Start(["Consumer reads<br>PolicyPeriods"]) --> A["GetPolicyPeriodCollection<br>constructs Criteria"]
	A --> B["BeforeRetrieve assigns<br>getPolicyPeriods, binds<br>apolicynum/aTopNPolPer"]
	B --> C["Framework executes<br>procedure against Oracle"]
	C --> D["AfterRetrieve reads rows"]
	D --> E{More rows?}
	E -->|Yes| F["New clsPolicyPeriod / Load /<br>Add to collection"]
	F --> E
	E -->|No| G["Return populated<br>clsPolicyPeriodCollection"]
	G --> H["GetCurrentPolicyPeriod /<br>GetLatestPolicyPeriodInfoPagePrinted /<br>GetDOIPolicyPeriod select a period"]
```

## Failure and edge-case behavior
- An empty result set yields an empty collection; `GetCurrentPolicyPeriod` and `GetLatestPolicyPeriodInfoPagePrinted` both return `Nothing` in that case rather than throwing.
- `GetLatestPolicyPeriodInfoPagePrinted` calls `IsInformationPagePrinted` for every renewal period it encounters until a match or an `isCurrentPolicyPeriod` short-circuit — this is a data-access call per iteration, not a cached lookup.*
- `GetDOISalesPlan`/`GetDOIFinalEvalDate` return string/date sentinels (`"Not Found"`, `Date.MinValue`) instead of `Nothing`/raising when no period is effective on the given date — callers must check for these sentinel values explicitly.*

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources
- `SAIF.Business.View.Policy/clsPolicyPeriodCollection.vb`
- `SAIF.Business.View.Policy/clsPolicyData.vb`
